/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */

package br.uniceub.fsw.indicadores.dao;

import br.uniceub.fsw.arquitetura.persistencia.dao.BaseDAO;
import br.uniceub.fsw.arquitetura.persistencia.dao.ConstrutorSQL;
import br.uniceub.fsw.indicadores.vo.ObjetivoVO;
import br.uniceub.fsw.indicadores.vo.PlanoMedicaoVO;
import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Data Access Object da entidade Objetivo. Essa classe é responsável por todas as 
 * operações de banco de dados relacionadas à entidade.
 * 
 * @author Marcos Mello Nobrega Soares 20136178
 */
public class ObjetivoDAO extends BaseDAO<ObjetivoVO> {

    @Override
    public void inserir(ObjetivoVO entidade) {

        ConstrutorSQL query = new ConstrutorSQL();

        query.append("INSERT INTO TB_Objetivo(NO_Objetivo, DS_Objetivo, CD_TipoObjetivo, ST_ObjetivoAtivo)");
        query.append("VALUES (?, ?, ?, ?)");

        List<?> parametros = criarParametros(entidade.getNoObjetivo(),
                entidade.getDsObjetivo(), entidade.getCdTipoObjetivo(), entidade.getStObjetivoAtivo());

        Integer idGerado = ((Long) executarInsercao(query.toString(), parametros)).intValue();

        entidade.setIdObjetivo(idGerado);
    }

    @Override
    public void alterar(ObjetivoVO entidade) {

        ConstrutorSQL query = new ConstrutorSQL();

        query.append("UPDATE TB_Objetivo SET NO_Objetivo = ?,");
        query.append("DS_Objetivo = ?,");
        query.append("CD_TipoObjetivo = ?,");
        query.append("ST_ObjetivoAtivo = ?");
        query.append("WHERE ID_Objetivo = ?");

        List<?> parametros = criarParametros(entidade.getNoObjetivo(),
                entidade.getDsObjetivo(),entidade.getCdTipoObjetivo(),
                entidade.getStObjetivoAtivo(),
                entidade.getIdObjetivo());

        executarAlteracao(query.toString(), parametros);
    }

    @Override
    public void excluir(ObjetivoVO entidade) {

        ConstrutorSQL query = new ConstrutorSQL();

        query.append("DELETE FROM TB_Objetivo");
        query.append("WHERE ID_Objetivo = ?");

        executarAlteracao(query.toString(), criarParametros(entidade.getIdObjetivo()));
    }

    @Override
    public ObjetivoVO consultarPorId(Serializable id) {

        ObjetivoVO entidade = null;

        ConstrutorSQL query = new ConstrutorSQL();

        query.append("SELECT * FROM TB_Objetivo T WHERE T.ID_Objetivo = ?");

        entidade = consultarUm(query.toString(), criarParametros(id));

        return entidade;
    }

    @Override
    public List<ObjetivoVO> consultarPorExemplo(ObjetivoVO exemplo) {

        List<ObjetivoVO> listaRetorno = null;

        ConstrutorSQL query = new ConstrutorSQL();

        query.append("SELECT * FROM TB_Objetivo T WHERE 1=1");

        mapearQueryParaExemplo(query, exemplo);

        listaRetorno = consultar(query.toString(), recuperarParametros());

        return listaRetorno;
    }
    
    /**
     * Retorna a lista de Objetivos associados a dado plano de medição.
     * 
     * @param plano de medição
     * @param exemplo de objetivo para filtragem
     * @return
     */
    public List<ObjetivoVO> consultarPorPlanoMedicao(PlanoMedicaoVO plano, ObjetivoVO exemplo) {

        List<ObjetivoVO> listaRetorno = null;

        if(plano != null) {
            ConstrutorSQL query = new ConstrutorSQL();

            query.append("" +
                    "SELECT " +
                    "   O.* " +
                    "FROM " +
                    "   TB_Objetivo O " +
                    "       INNER JOIN TA_PlanoMedicaoObjetivo PO " +
                    "           ON PO.CD_Objetivo = O.ID_Objetivo " +
                    "WHERE " +
                    "   PO.CD_PlanoMedicao = ? AND O.ST_ObjetivoAtivo = 'S' ");
            
            adicionarParametro(plano.getIdPlanoMedicao());
                   
            if(exemplo != null)
                mapearQueryParaExemplo(query, exemplo);

            listaRetorno = consultar(query.toString(), recuperarParametros());
        }
        
        return listaRetorno;
    }
    
    /**
     * Retorna a lista de Objetivos associados a dado plano de medição.
     * 
     * @param plano de medição
     * @return
     */
    public List<ObjetivoVO> consultarPorPlanoMedicao(PlanoMedicaoVO plano) {
        return consultarPorPlanoMedicao(plano, null);
    }

    @Override
    protected ObjetivoVO extrairObjetoResultado(ResultSet rs) throws SQLException {

        ObjetivoVO entidade = new ObjetivoVO();
        
        entidade.setIdObjetivo(new Integer(rs.getInt("ID_Objetivo")));        
        entidade.setNoObjetivo(rs.getString("NO_Objetivo"));
        entidade.setDsObjetivo(rs.getString("DS_Objetivo"));
        entidade.setStObjetivoAtivo(rs.getString("ST_ObjetivoAtivo"));
        entidade.setCdTipoObjetivo(new Integer(rs.getInt("CD_TipoObjetivo")));

        return entidade;
    }

    @Override
    protected void mapearQueryParaExemplo(ConstrutorSQL query, ObjetivoVO exemplo) {
        
        if (exemplo.getNoObjetivo() != null && !exemplo.getNoObjetivo().isEmpty()) {
            query.append("AND T.NO_Objetivo LIKE ?");
            adicionarParametro("%" + exemplo.getNoObjetivo() + "%");
        }

        if (exemplo.getDsObjetivo() != null && !exemplo.getDsObjetivo().isEmpty()) {
            query.append("AND T.DS_Objetivo LIKE ?");
            adicionarParametro("%" + exemplo.getDsObjetivo() + "%");
        }
        
        if (exemplo.getCdTipoObjetivo() != null) {
            query.append("AND T.CD_TipoObjetivo = ?");
            adicionarParametro(exemplo.getCdTipoObjetivo());
        }        
        
        if (exemplo.getStObjetivoAtivo() != null) {
            query.append("AND T.ST_ObjetivoAtivo = ?");
            adicionarParametro(exemplo.getStObjetivoAtivo());
        }
    }
}
